home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / WarpQuake / Src / conproc.c < prev    next >
C/C++ Source or Header  |  2000-05-22  |  7KB  |  366 lines

  1. /*
  2. Copyright (C) 1996-1997 Id Software, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  12.  
  13. See the GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. */
  20. // conproc.c
  21.  
  22. #include <windows.h>
  23. #include "conproc.h"
  24. #include "quakedef.h"
  25.  
  26. HANDLE    heventDone;
  27. HANDLE    hfileBuffer;
  28. HANDLE    heventChildSend;
  29. HANDLE    heventParentSend;
  30. HANDLE    hStdout;
  31. HANDLE    hStdin;
  32.  
  33. DWORD RequestProc (DWORD dwNichts);
  34. LPVOID GetMappedBuffer (HANDLE hfileBuffer);
  35. void ReleaseMappedBuffer (LPVOID pBuffer);
  36. BOOL GetScreenBufferLines (int *piLines);
  37. BOOL SetScreenBufferLines (int iLines);
  38. BOOL ReadText (LPTSTR pszText, int iBeginLine, int iEndLine);
  39. BOOL WriteText (LPCTSTR szText);
  40. int CharToCode (char c);
  41. BOOL SetConsoleCXCY(HANDLE hStdout, int cx, int cy);
  42.  
  43.  
  44. void InitConProc (HANDLE hFile, HANDLE heventParent, HANDLE heventChild)
  45. {
  46.     DWORD    dwID;
  47.     CONSOLE_SCREEN_BUFFER_INFO    info;
  48.     int        wheight, wwidth;
  49.  
  50. // ignore if we don't have all the events.
  51.     if (!hFile || !heventParent || !heventChild)
  52.         return;
  53.  
  54.     hfileBuffer = hFile;
  55.     heventParentSend = heventParent;
  56.     heventChildSend = heventChild;
  57.  
  58. // so we'll know when to go away.
  59.     heventDone = CreateEvent (NULL, FALSE, FALSE, NULL);
  60.  
  61.     if (!heventDone)
  62.     {
  63.         Con_SafePrintf ("Couldn't create heventDone\n");
  64.         return;
  65.     }
  66.  
  67.     if (!CreateThread (NULL,
  68.                        0,
  69.                        (LPTHREAD_START_ROUTINE) RequestProc,
  70.                        0,
  71.                        0,
  72.                        &dwID))
  73.     {
  74.         CloseHandle (heventDone);
  75.         Con_SafePrintf ("Couldn't create QHOST thread\n");
  76.         return;
  77.     }
  78.  
  79. // save off the input/output handles.
  80.     hStdout = GetStdHandle (STD_OUTPUT_HANDLE);
  81.     hStdin = GetStdHandle (STD_INPUT_HANDLE);
  82.  
  83. // force 80 character width, at least 25 character height
  84.     SetConsoleCXCY (hStdout, 80, 25);
  85. }
  86.  
  87.  
  88. void DeinitConProc (void)
  89. {
  90.     if (heventDone)
  91.         SetEvent (heventDone);
  92. }
  93.  
  94.  
  95. DWORD RequestProc (DWORD dwNichts)
  96. {
  97.     int        *pBuffer;
  98.     DWORD    dwRet;
  99.     HANDLE    heventWait[2];
  100.     int        iBeginLine, iEndLine;
  101.     
  102.     heventWait[0] = heventParentSend;
  103.     heventWait[1] = heventDone;
  104.  
  105.     while (1)
  106.     {
  107.         dwRet = WaitForMultipleObjects (2, heventWait, FALSE, INFINITE);
  108.  
  109.     // heventDone fired, so we're exiting.
  110.         if (dwRet == WAIT_OBJECT_0 + 1)    
  111.             break;
  112.  
  113.         pBuffer = (int *) GetMappedBuffer (hfileBuffer);
  114.         
  115.     // hfileBuffer is invalid.  Just leave.
  116.         if (!pBuffer)
  117.         {
  118.             Con_SafePrintf ("Invalid hfileBuffer\n");
  119.             break;
  120.         }
  121.  
  122.         switch (pBuffer[0])
  123.         {
  124.             case CCOM_WRITE_TEXT:
  125.             // Param1 : Text
  126.                 pBuffer[0] = WriteText ((LPCTSTR) (pBuffer + 1));
  127.                 break;
  128.  
  129.             case CCOM_GET_TEXT:
  130.             // Param1 : Begin line
  131.             // Param2 : End line
  132.                 iBeginLine = pBuffer[1];
  133.                 iEndLine = pBuffer[2];
  134.                 pBuffer[0] = ReadText ((LPTSTR) (pBuffer + 1), iBeginLine, 
  135.                                        iEndLine);
  136.                 break;
  137.  
  138.             case CCOM_GET_SCR_LINES:
  139.             // No params
  140.                 pBuffer[0] = GetScreenBufferLines (&pBuffer[1]);
  141.                 break;
  142.  
  143.             case CCOM_SET_SCR_LINES:
  144.             // Param1 : Number of lines
  145.                 pBuffer[0] = SetScreenBufferLines (pBuffer[1]);
  146.                 break;
  147.         }
  148.  
  149.         ReleaseMappedBuffer (pBuffer);
  150.         SetEvent (heventChildSend);
  151.     }
  152.  
  153.     return 0;
  154. }
  155.  
  156.  
  157. LPVOID GetMappedBuffer (HANDLE hfileBuffer)
  158. {
  159.     LPVOID pBuffer;
  160.  
  161.     pBuffer = MapViewOfFile (hfileBuffer,
  162.                             FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
  163.  
  164.     return pBuffer;
  165. }
  166.  
  167.  
  168. void ReleaseMappedBuffer (LPVOID pBuffer)
  169. {
  170.     UnmapViewOfFile (pBuffer);
  171. }
  172.  
  173.  
  174. BOOL GetScreenBufferLines (int *piLines)
  175. {
  176.     CONSOLE_SCREEN_BUFFER_INFO    info;                              
  177.     BOOL                        bRet;
  178.  
  179.     bRet = GetConsoleScreenBufferInfo (hStdout, &info);
  180.         
  181.     if (bRet)
  182.         *piLines = info.dwSize.Y;
  183.  
  184.     return bRet;
  185. }
  186.  
  187.  
  188. BOOL SetScreenBufferLines (int iLines)
  189. {
  190.  
  191.     return SetConsoleCXCY (hStdout, 80, iLines);
  192. }
  193.  
  194.  
  195. BOOL ReadText (LPTSTR pszText, int iBeginLine, int iEndLine)
  196. {
  197.     COORD    coord;
  198.     DWORD    dwRead;
  199.     BOOL    bRet;
  200.  
  201.     coord.X = 0;
  202.     coord.Y = iBeginLine;
  203.  
  204.     bRet = ReadConsoleOutputCharacter(
  205.         hStdout,
  206.         pszText,
  207.         80 * (iEndLine - iBeginLine + 1),
  208.         coord,
  209.         &dwRead);
  210.  
  211.     // Make sure it's null terminated.
  212.     if (bRet)
  213.         pszText[dwRead] = '\0';
  214.  
  215.     return bRet;
  216. }
  217.  
  218.  
  219. BOOL WriteText (LPCTSTR szText)
  220. {
  221.     DWORD            dwWritten;
  222.     INPUT_RECORD    rec;
  223.     char            upper, *sz;
  224.  
  225.     sz = (LPTSTR) szText;
  226.  
  227.     while (*sz)
  228.     {
  229.     // 13 is the code for a carriage return (\n) instead of 10.
  230.         if (*sz == 10)
  231.             *sz = 13;
  232.  
  233.         upper = toupper(*sz);
  234.  
  235.         rec.EventType = KEY_EVENT;
  236.         rec.Event.KeyEvent.bKeyDown = TRUE;
  237.         rec.Event.KeyEvent.wRepeatCount = 1;
  238.         rec.Event.KeyEvent.wVirtualKeyCode = upper;
  239.         rec.Event.KeyEvent.wVirtualScanCode = CharToCode (*sz);
  240.         rec.Event.KeyEvent.uChar.AsciiChar = *sz;
  241.         rec.Event.KeyEvent.uChar.UnicodeChar = *sz;
  242.         rec.Event.KeyEvent.dwControlKeyState = isupper(*sz) ? 0x80 : 0x0; 
  243.  
  244.         WriteConsoleInput(
  245.             hStdin,
  246.             &rec,
  247.             1,
  248.             &dwWritten);
  249.  
  250.         rec.Event.KeyEvent.bKeyDown = FALSE;
  251.  
  252.         WriteConsoleInput(
  253.             hStdin,
  254.             &rec,
  255.             1,
  256.             &dwWritten);
  257.  
  258.         sz++;
  259.     }
  260.  
  261.     return TRUE;
  262. }
  263.  
  264.  
  265. int CharToCode (char c)
  266. {
  267.     char upper;
  268.         
  269.     upper = toupper(c);
  270.  
  271.     switch (c)
  272.     {
  273.         case 13:
  274.             return 28;
  275.  
  276.         default:
  277.             break;
  278.     }
  279.  
  280.     if (isalpha(c))
  281.         return (30 + upper - 65); 
  282.  
  283.     if (isdigit(c))
  284.         return (1 + upper - 47);
  285.  
  286.     return c;
  287. }
  288.  
  289.  
  290. BOOL SetConsoleCXCY(HANDLE hStdout, int cx, int cy)
  291. {
  292.     CONSOLE_SCREEN_BUFFER_INFO    info;
  293.     COORD                        coordMax;
  294.  
  295.     coordMax = GetLargestConsoleWindowSize(hStdout);
  296.  
  297.     if (cy > coordMax.Y)
  298.         cy = coordMax.Y;
  299.  
  300.     if (cx > coordMax.X)
  301.         cx = coordMax.X;
  302.  
  303.     if (!GetConsoleScreenBufferInfo(hStdout, &info))
  304.         return FALSE;
  305.  
  306. // height
  307.     info.srWindow.Left = 0;         
  308.     info.srWindow.Right = info.dwSize.X - 1;                
  309.     info.srWindow.Top = 0;
  310.     info.srWindow.Bottom = cy - 1;          
  311.  
  312.     if (cy < info.dwSize.Y)
  313.     {
  314.         if (!SetConsoleWindowInfo(hStdout, TRUE, &info.srWindow))
  315.             return FALSE;
  316.  
  317.         info.dwSize.Y = cy;
  318.  
  319.         if (!SetConsoleScreenBufferSize(hStdout, info.dwSize))
  320.             return FALSE;
  321.     }
  322.     else if (cy > info.dwSize.Y)
  323.     {
  324.         info.dwSize.Y = cy;
  325.  
  326.         if (!SetConsoleScreenBufferSize(hStdout, info.dwSize))
  327.             return FALSE;
  328.  
  329.         if (!SetConsoleWindowInfo(hStdout, TRUE, &info.srWindow))
  330.             return FALSE;
  331.     }
  332.  
  333.     if (!GetConsoleScreenBufferInfo(hStdout, &info))
  334.         return FALSE;
  335.  
  336. // width
  337.     info.srWindow.Left = 0;         
  338.     info.srWindow.Right = cx - 1;
  339.     info.srWindow.Top = 0;
  340.     info.srWindow.Bottom = info.dwSize.Y - 1;               
  341.  
  342.     if (cx < info.dwSize.X)
  343.     {
  344.         if (!SetConsoleWindowInfo(hStdout, TRUE, &info.srWindow))
  345.             return FALSE;
  346.  
  347.         info.dwSize.X = cx;
  348.     
  349.         if (!SetConsoleScreenBufferSize(hStdout, info.dwSize))
  350.             return FALSE;
  351.     }
  352.     else if (cx > info.dwSize.X)
  353.     {
  354.         info.dwSize.X = cx;
  355.  
  356.         if (!SetConsoleScreenBufferSize(hStdout, info.dwSize))
  357.             return FALSE;
  358.  
  359.         if (!SetConsoleWindowInfo(hStdout, TRUE, &info.srWindow))
  360.             return FALSE;
  361.     }
  362.  
  363.     return TRUE;
  364. }
  365.      
  366.